package util.arff;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import tmhprediction.classification.SolDiscriminationBasedOnFreeInsertionEnergy;

public abstract class AbstractArffGenerator {

	protected String structPath = "";
	protected String resultPath = "";
	protected List<String> proteins;
	protected boolean considerZeros;
	abstract public void generateArff();
	
	protected void createArffFileForIMP(char[] array, char[] arraySequence, String arffAbsolutePath, boolean includeEnergy) throws IOException {
	    File f = new File(arffAbsolutePath);
	    if(!f.exists()){
	    	f.createNewFile();
	    }
		BufferedWriter writer = new BufferedWriter(new FileWriter(f));
		writer.write("%Created by Group77");
		writer.newLine();
		writer.write("@RELATION\t'" + "prot.arff'");
		writer.newLine();
		writer.newLine();
		writer.write("@ATTRIBUTE\tpos\tNUMERIC");
		writer.newLine();
		writer.write("@ATTRIBUTE\trelpos\tNUMERIC");
		writer.newLine();
		
		//Energy feature
		if (includeEnergy) {
		    writer.write("@ATTRIBUTE\tdeltagapp\tNUMERIC");
		    writer.newLine();
		}
		if (considerZeros) {
			writer.write("@ATTRIBUTE\tclass\t{+,-,0}");
		} else {
			writer.write("@ATTRIBUTE\tclass\t{+,-}");
		}
		writer.newLine();
		writer.newLine();
		writer.write("@DATA");
		DecimalFormat dFormat = new DecimalFormat("#0.00");
		
//		double 
		
		for (int i = 0; i < array.length; i++) {
			writer.newLine();
			
			//Calculate energy at this position
			
			String energyString = includeEnergy ? calculateEnergy(arraySequence, i) + "," : "";
			writer.write(i + ","
					+ dFormat.format(Math.round(((double)i / (array.length - 1)) * 100) / 100.0)   + ","
					 + energyString
					+ evaluateChar(array[i]));
		}
		writer.close();
	}
	
	protected static double calculateEnergy(char[] arr, int index)
	{
		//prepare sequence so the calculation function can handle it
		String seqAsString = "";
		for(char a : arr)
		{
			seqAsString += a;
		}
		
		String substring = "";
		
		if(index < 9)
		{
			//window has to be extended to the left with nonsense sequence that will then be handled as energy 0 by the energy calculator
			substring = seqAsString.substring(0, 10+index);
			substring  = StringUtils.repeat('X', 9-index) + substring;
		}
		else
			{
				if(index > seqAsString.length()-10) // right end
				{
//					System.out.println("in here");
					substring = seqAsString.substring(index-9,seqAsString.length());
					substring = substring + StringUtils.repeat('X', 9-(seqAsString.length() - index));
				}
				else
				{
					substring = seqAsString.substring(index-9, index+10);
				}
			}
		
		String[] split = substring.split("");
		List<String> list = new ArrayList<String>(Arrays.asList(split));
		list.remove(0);
		
		return SolDiscriminationBasedOnFreeInsertionEnergy.calcEnergy(list);
	}
	
	private String evaluateChar(char c) {
		String result = "";
		if (c == 'H' || c == 'L') {
			result = "+";
		} else if (c == ' ' && considerZeros) {
			result = "0";
		} else {
			result = "-";
		}
		return result;
	}
	
	protected void createArffFileForSOL(String name, String arffAbsolutePath, String solQueryInPath, boolean includeEnergy) throws IOException {
	    File f=new File(arffAbsolutePath);
	    if(!f.exists()){
	    	f.createNewFile();
	    }
		BufferedWriter writer = new BufferedWriter(new FileWriter(f));
		writer.write("%Created by Group77");
		writer.newLine();
		writer.write("@RELATION\t'" + "prot.arff'");
		writer.newLine();
		writer.newLine();
		writer.write("@ATTRIBUTE\tpos\tNUMERIC");
		writer.newLine();
		writer.write("@ATTRIBUTE\trelpos\tNUMERIC");
		writer.newLine();
		
		//Energy feature
		if (includeEnergy) {
            		writer.write("@ATTRIBUTE\tdeltagapp\tNUMERIC");
            		writer.newLine();
		}
		if (considerZeros) {
			writer.write("@ATTRIBUTE\tclass\t{+,-,0}");
		} else {
			writer.write("@ATTRIBUTE\tclass\t{+,-}");
		}
		writer.newLine();
		writer.newLine();
		writer.write("@DATA");
		
		String sequence = getSequenceForSolProtein(solQueryInPath, name);

		char[] array = sequence.toCharArray();
		
		int solLength = sequence.length();
		DecimalFormat dFormat = new DecimalFormat("#0.00");
		for (int i = 0; i < solLength; i++) {
			writer.newLine();
			
			//Calculate energy at this position
			String energyString = includeEnergy ? calculateEnergy(array, i) + "," : "";
			writer.write(i + ","
					+ dFormat.format(Math.round(((double)i / (solLength - 1)) * 100) / 100.0)   + ","
					 + energyString
					+ "-");
//			writer.write(i + "," +
////			dFormat.format(Math.round(((double)i / (solLength - 1)) * 100) / 100.0) + "," + 	TODO
//					energyString
//					+ "-");
		}
		writer.close();
	}
	
	protected String getSequenceForSolProtein(String solQueryInPath, String name) throws IOException {
		BufferedReader reader = new BufferedReader(new FileReader(solQueryInPath));
		reader.readLine();
		String resultString = "";
		String thisLine;
		while ((thisLine = reader.readLine())!= null) {
			resultString = resultString + thisLine;
		}
		reader.close();
		
		return resultString;
	}
}
